home *** CD-ROM | disk | FTP | other *** search
/ Lattice ISP Synario Start… & ISP Encyclopedia 1997 / LATTICE Synario.iso / ispcode / source / ispcode.c < prev    next >
Encoding:
Text File  |  1997-06-24  |  42.0 KB  |  988 lines

  1. /*****************************************************************************
  2. *                            ispCODE.c                                       *
  3. * ispCODE for ispLSI Devices Using the Industry Standard ISP State Machine   *
  4. *         and for ispLSI Devices Using the JTAG TAP controller.              *
  5. *           Lattice Semiconductor Corp. Copyright 1996,1997.                 *
  6. *                                                                            *
  7. * ISP(tm) daisy chain turbo programming is supported by ispCODE.             *
  8. *                                                                            *
  9. * The function of this ispCODE is to utilize the Industry Standard ISP state *
  10. * machine in the ispLSI devices or the JTAG TAP for programming and          *
  11. * verification. The input file for ispCODE is FULL ispSTREAM files or Super  *
  12. * FULL ispSTREAM files. This file is obtained by combining the file icode5a.c*
  13. * particularily for ISP chain configuration and the file icode5c.c for       *
  14. * ispJTAG chain configuration. The program is compiled as xturbo.exe for     *
  15. * programming demonstration on PC. This program is also provided so that     *
  16. * it can be used as a command line production programming program on PC.     *
  17. * As such the elaborate scheme to ensure correct programming pulse on PC is  *
  18. * retained on the pulse_width() function.                                    *
  19. *                                                                            *
  20. * This version of ispCODE is the much simplified version of ispCODE V3.xx    *
  21. * by removing the PES checking, the post BULK ERASE verification and the     *
  22. * simultaneous shifting data in and out. The programming time is thus a bit  *
  23. * longer than V3.xx due to the additional time needed to shift data in and   *
  24. * out separately. It is a very little price to pay for a 50% reduction in    *
  25. * code size which is especially critical for embedded controller programming *
  26. * where resources is extremely limited.                                      *
  27. *                                                                            *
  28. * The file size of Super FULL ispSTREAM is about 30% less than the FULL      *
  29. * ispSTREAM. The saving comes from replacing long chain of 0xFFs with        *
  30. * the number of consecutive 0xFF bytes. For example:                         *
  31. *           0xFF,0xFF,0xFF,0xC3 is reduced to 0xFF,0x03,0xC3                 *
  32. *                                                                            *
  33. * The Super FULL ispSTREAM file is created by the command line program       *
  34. * dld2isp.exe v4.03 with the option sf selected. For example: type           *
  35. *                  dld2isp  design.dld sf                                    *
  36. *                                                                            *
  37. * All ispLSI devices support the Lattice Semiconductor pioneered UES         *
  38. * feature. If the UES is appended into the JEDEC files using the UES editor  *
  39. * on ISP Daisy Chain Download program, the resultant ispSTREAM will take     *
  40. * care of programming and verifying the UES data.                            *
  41. *                                                                             *
  42. * Note: The UES length of most ispLSI devices is the same as their data      *
  43. *       length. If it is found on the data book that they are not the same   *
  44. *       such as ispLSI 3256 and 6192 devices, only the last 160 bits are     *
  45. *       referred to as UES. For example: The data length of ispLSI 3256      *
  46. *       devices is 338 bits and the UES length is 160 bits as shown in the   *
  47. *       data book. Pulse SCLK 338-160=178 times to flush out the phantum     *
  48. *       bits first then read the 1st UES bit.                                *
  49. *                                                                            *
  50. * Revision history:                                                          *
  51. *   5.000  Howard Tang  01/08/97 Created by combining ispcode.c V3.0x,       *
  52. *                                 icode5a.c and icode5c.c.                   *
  53. *   5.001  Howard Tang  01/17/97 Fixed bugs on supporting 3256E,3160 & GDX   *
  54. *                                devices.                                    *
  55. *****************************************************************************/
  56.  
  57. #include <stdio.h>
  58. #include <dos.h>
  59. #include <stdlib.h>
  60. #include <string.h>
  61. #include "lattice.h"
  62.  
  63. /*Global variables */
  64. static short int      jtag=0;      /*the flag is true if ispJTAG chain*/
  65. static short int      bit=0;       /*the current bit read from ispSTREAM*/
  66. static unsigned char curch;        /*the current data from ispSTREAM*/
  67. FILE  *fp;                         /*the pointer to the ispSTREAM file*/
  68. static short int inputport=inport1,       /*port address for the input port*/
  69.                  outputport=outport1;      /*port address for the output port*/
  70. static short int isp_pins=NUL;    /*3.02 holds the value of parallel port*/
  71.                                  /*     intialized to drive all pins to LOW*/
  72. static char     state;           /*4.0  Keep track of the state of the TAP
  73.                                         state machine.*/
  74.  
  75. /*prototypes*/
  76. void            pulse_width(unsigned int milliseconds);
  77. void            execute(void);
  78. void            move_to_id_state(void);
  79. short int       ispstream_pump(short int operation, short int *end);
  80. void            error_handler(short int rcode, char *message);
  81. unsigned char   GetByte(void);
  82. void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse, 
  83.                          short int *ProgramPulse, short int *RowLength, 
  84.                          unsigned short int *DataSize, 
  85.                          unsigned short int *IDStreamLength);
  86. char ispRead(unsigned short int DataSize, unsigned char *OutData);
  87. void ReadispSTREAMDataSize(unsigned short int  *DataSize);
  88. void ReadispSTREAMData(unsigned short int *DataSize, unsigned char *InData,
  89.                        char SF);
  90. char ispInstruction(char SF,char Send);
  91. void ispData( unsigned char *InData, unsigned short int DataSize);
  92. void program_enable(short int chips);
  93. void device_enable(short int chips);
  94.  
  95. /***************************************************************************
  96.    Function: isp_setpin(byte pins, byte value)
  97.  
  98.    Purpose:
  99.    To apply the specified value to the pins indicated. This routine will
  100.    likely be modified for specific systems. As an example, this code
  101.    is for the PC, as described below.
  102.  
  103.    This routine uses the IBM-PC standard Parallel port, along with the
  104.    schematic shown in Lattice documentation, to apply the signals to the
  105.    programming loop. 
  106.  
  107.    PC Parallel port pin    Signal name
  108.    --------------------    -----------
  109.          2                   out_SDI
  110.          3                   out_SCLK
  111.          4                   out_MODE
  112.          5                   out_ISP
  113.          6                   out_RESET
  114.          7                   DO5
  115.          8                   out_SENSE_CABLE_OUT    
  116.          9                   DO7
  117.          10                  in_SDO
  118.          12                  in_CABLE_SENSE_IN
  119.          15                  in_VCC_OK 
  120.          20                  GND
  121.  
  122.    Parameters:
  123.          - pins, which is actually a set of bit flags (defined in lattice.h) 
  124.            that correspond to the bits of the data port. Each of the I/O port 
  125.            bits that drives an isp programming pin is assigned a flag 
  126.            (through a #define) corresponding to the signal it drives. To 
  127.            change the value of more than one pin at once, the flags are added 
  128.            together, much like file access flags are.
  129.  
  130.            The bit flags are only set if the pin is to be changed. Bits that 
  131.            do not have their flags set do not have their levels changed. The 
  132.            state of the port is always manintained in the static global 
  133.            variable isp_pins, so that each pin can be addressed individually 
  134.            without disturbing the others.
  135.  
  136.          - value, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two
  137.            values are valid. Any non-zero number sets the pin(s) high.
  138.  
  139.    Returns: nothing.
  140.  
  141.  
  142. **************************************************************************/
  143. void isp_setpin(unsigned char pins, unsigned char value)
  144. {
  145.   /* isp_pins is a Global value that keeps track of the current state
  146.      of the pins  */
  147.  
  148.   if( value ) /* set flagged pins HIGH */
  149.       isp_pins = pins | isp_pins;
  150.   else        /* set flagged pins LOW */
  151.       isp_pins = ~pins & isp_pins;
  152.  
  153.   /* value is put on Parallel port pins */
  154.   outp(outputport, isp_pins);
  155.  
  156. } /* isp_setpin() */
  157.  
  158.  
  159. /***************************************************************************
  160.    Function: isp_SDO()
  161.  
  162.    Purpose:
  163.    To get the value of the SDO pin from the input port.
  164.  
  165.    This routine is specific to the PC parallel port setup, but can easily
  166.    be changed to address each user's hardware.
  167.  
  168.    Parameters: none
  169.  
  170.    Returns: The value of SDO, as a byte, with a value of either 0 or 1.
  171.  
  172.    Notes:
  173.    - This routine uses the I/O port addresses contained in the global
  174.      variable inputport, declared in the lattice.h file. 
  175.  
  176.  
  177. ****************************************************************************/
  178. unsigned char isp_SDO(void)
  179. {
  180.  /* MUST return either 0x00 or 0x01 */
  181.   return( (unsigned char) ((inp(inputport) & in_SDO ) ? HIGH : LOW) );
  182.  
  183. } /* isp_SDO() */
  184.  
  185.  
  186. /*************************************************************
  187. *                                                            *
  188. *                         PULSE_WIDTH                        *
  189. *                                                            *
  190. *************************************************************/
  191.  
  192.  
  193. void            pulse_width(unsigned int milliseconds)
  194. {
  195.    static unsigned int ticks_per_ms = 0;
  196.    static int      mode2 = false;
  197.    static long     pre_ticks = 0L;
  198.    unsigned int    start,
  199.                    end;
  200.    long            ticks,
  201.                    cur_ticks;
  202.    static int      count = 0;
  203.  
  204.  
  205.    cur_ticks = 0L;
  206.    outp(0x43, 0x00);
  207.    start = inp(0x40);
  208.    start += inp(0x40) << 8;
  209.    if (ticks_per_ms == 0) {
  210.       ticks_per_ms = (0xFFFF / 55) * 2;
  211.       if (start & 0x0001) {
  212.          ticks_per_ms = 0xFFFF / 55;
  213.          mode2 = true;
  214.       }
  215.    }
  216.    ticks = (long) ticks_per_ms *milliseconds;
  217.    while (ticks > 0L) {
  218.       if (pre_ticks == 0L)
  219.          pre_ticks = cur_ticks;
  220.       else if (count < 5) {                      /* calibration count *//* keep
  221.                                                   * the most conservative ticks
  222.                                                   * per loop as calibrated
  223.                                                   * value */
  224.          if (pre_ticks > cur_ticks)
  225.             pre_ticks = cur_ticks;
  226.          count++;
  227.       }
  228.       outp(0x43, 0x00);
  229.       end = inp(0x40);
  230.       end += inp(0x40) << 8;
  231.       if ((!mode2) && (end & 0x0001)) {
  232.          ticks_per_ms = 0xFFFF / 55;
  233.          ticks -= (long) ticks_per_ms *milliseconds;
  234.          mode2 = true;
  235.          if (ticks <= 0L)
  236.             break;                               /* done already */
  237.       }
  238.       cur_ticks = (long) (start - end);          /* number of ticks elapsed */
  239.       if (cur_ticks == 0L) {                     /* this can happen only when
  240.                                                   * in Window DOS */
  241.          cur_ticks = pre_ticks;
  242.          ticks -= cur_ticks;
  243.       } else if (cur_ticks > 0L)
  244.          ticks -= cur_ticks;
  245.       else {
  246.          cur_ticks = (long) (0xFFFF - end + start);
  247.          ticks -= cur_ticks;
  248.       }
  249.       /* safe guard against stolen ticks in Window DOS */
  250.       if ((pre_ticks > 0L) && ((cur_ticks - pre_ticks) > (ticks_per_ms / 4))) {
  251.          ticks += (cur_ticks - pre_ticks);
  252.          cur_ticks = pre_ticks;
  253.       }
  254.       start = end;
  255.    }
  256. }
  257.  
  258.  
  259.  
  260.  
  261. /*************************************************************
  262. *                                                            *
  263. *                      GETBYTE                               *
  264. * This procedure reads a byte from the ispSTREAM.            *
  265. *************************************************************/
  266. unsigned char GetByte()
  267. {
  268.  return (fgetc(fp));
  269. }
  270.  
  271.  
  272. /*************************************************************
  273. *                                                            *
  274. *                      SCLOCK                                *
  275. * This procedure apply a clock to TCK.                       *
  276. *************************************************************/
  277. void sclock(void)
  278. {
  279.  isp_setpin(out_SCLK,HIGH);
  280.  isp_setpin(out_SCLK,LOW);
  281. }
  282.  
  283. /*************************************************************
  284. *                                                            *
  285. *                       SHIFT/EXECUTE                        *
  286. * This procedure walk all devices in the daisy chain from a  *
  287. * given state to the next desirable state.                   * 
  288. *                                                            *
  289. *If at Idle state when enter then move to Shift-IR state.    *
  290. *If at Shift-IR state when enter then move to Shift-DR state.*
  291. *If at Shift-DR state when enter then move to Shift-IR state.*
  292. *If at Shift-IR state and state is set to time_state when    *
  293. *enter then move to Idle state.                              *
  294. *************************************************************/
  295. void execute()
  296. {
  297.  short int i,count;
  298.  /*for ISP chain*/
  299.    if (!jtag) 
  300.       {isp_setpin(out_MODE, HIGH);
  301.        isp_setpin(out_SDI,  HIGH);
  302.        sclock();
  303.        isp_setpin(out_SDI,  LOW);
  304.        isp_setpin(out_MODE, LOW);
  305.        return;
  306.       }
  307.  /*for ispJTAG chain*/
  308.      if (state==time_state) 
  309.         {count = 1;   /*move from shift-IR to Idle state to start timing*/ 
  310.          state = idle_state;
  311.         }
  312.      else if (state==shift_state) 
  313.              {count = 2;  /*move from shift-IR to shift-DR*/
  314.               state = execute_state;
  315.              } 
  316.      else if (state==idle_state)
  317.              {count = 2;  /*move from Idle to shift-IR state*/
  318.               state = shift_state;
  319.              }
  320.      else if (state==execute_state)
  321.              {count = 3;  /*move from shift-DR to shift-IR*/
  322.               state = shift_state;
  323.              }
  324.      else count = 0;
  325.      isp_setpin(out_SCLK,LOW);
  326.      isp_setpin(out_MODE,LOW);
  327.      isp_setpin(out_SDI,LOW);
  328.      for (i=0; i<count; i++)
  329.          {
  330.           isp_setpin(out_MODE,HIGH);
  331.           sclock();
  332.          }
  333.      isp_setpin(out_MODE,LOW);
  334.      sclock();
  335.      if (count > 1) sclock();
  336.        /* at Shift-DR or Shift-IR state*/
  337. }
  338.  
  339.  
  340. /*************************************************************
  341. *                                                            *
  342. *                      MOVE TO ID STATE                      *
  343. * This procedure walk all devices in the daisy chain to the  *
  344. * Test-Logic-Reset state then Run-Test/Idle state.           *
  345. *                                                            *
  346. *************************************************************/
  347.  
  348. void move_to_id_state()
  349. {
  350. int i;
  351.        isp_setpin(out_SCLK,LOW);
  352.        isp_setpin(out_MODE+out_SDI,LOW);
  353.        pulse_width(2);
  354.        isp_setpin(out_MODE,HIGH);            
  355.        pulse_width(2);
  356.        isp_setpin(out_SCLK,HIGH);
  357.        pulse_width(2);
  358.        isp_setpin(out_SCLK,LOW);
  359.        for (i=0; i<6; i++) sclock();
  360.        isp_setpin(out_MODE,LOW);
  361.        pulse_width(2);
  362.        if (!jtag) return; /*skip if ISP chain*/
  363.        sclock();   /*device is in Idle state*/
  364.        state = idle_state;
  365. }
  366.  
  367. /*************************************************************
  368. *                                                            *
  369. *                      PROGRAM ENABLE                        *
  370. * perform the 3 read id instruction to get devices into      *
  371. * programming mode.                                          *
  372. *************************************************************/
  373.  
  374. void program_enable(short int chips)
  375. {
  376. short int i,j,loops;
  377.  
  378. if (!jtag) return;  /*skip for ISP chain*/
  379. for (loops=0; loops<3; loops++)
  380.     {
  381.      for (i=0; i<chips+1; i++)
  382.          for (j=0; j<5; j++)  /*send the instruction into TDI*/
  383.              {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH);  /*last bit*/ 
  384.               isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
  385.               sclock();
  386.              }     
  387.      for (i=0; i<3; i++) sclock();
  388.      isp_setpin(out_MODE,LOW);
  389.      sclock(); sclock(); /*devices at Shift-IR state*/
  390.      
  391.     }     
  392. }
  393.  
  394. /*************************************************************
  395. *                                                            *
  396. *                      DEVICE ENABLE                         *
  397. * perform the read id instruction to get devices into        *
  398. * functional mode.                                           *
  399. *************************************************************/
  400.  
  401. void device_enable(short int chips)
  402. {
  403. short int i,j;
  404.  
  405. if (!jtag) return;    /*skip for ISP chain*/
  406. /*devices come in at Shift-IR state*/
  407.      for (i=0; i<chips+1; i++)
  408.          for (j=0; j<5; j++)  /*send the instruction into TDI*/
  409.              {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH);  /*last bit*/ 
  410.               isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
  411.               sclock();
  412.              }     
  413.      sclock();                /*devices at Update-IR state*/
  414.      isp_setpin(out_MODE,LOW);
  415.      for (i=0; i<20; i++) sclock();   /*go and loop on Run-Test/Idle for 10uS*/
  416.      isp_setpin(out_MODE,HIGH);
  417.      for (i=0; i<3; i++) sclock();   /*devices at Test-Logic-Reset and active*/
  418. }     
  419.  
  420. /**********************************************************************
  421. *                                                                     *
  422. *                     READ_ISPSTREAM_HEADER                           *
  423. * Extract the header from the ispSTREAM file.                         *
  424. * Return                                                              *
  425. *     ChainLength--------number of ispLSI devices in the              *
  426. *                        given daisy  chain.                          *
  427. *     ErasePulse---------pulse width in mS for device                 *
  428. *                        bulk erase.                                  *
  429. *     ProgramPulse-------pulse width in mS for device                 *
  430. *                        row by row programming.                      *
  431. *     RowLength----------the number of rows of data +UES              *
  432. *     DataSize-----------the largest size of each row of data.        *
  433. *     BEVend-------------the end of Bulk Erase verify.                *
  434. ***********************************************************************/
  435. void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse, 
  436.                          short int *ProgramPulse, short int *RowLength,
  437.                          unsigned short int *DataSize,
  438.                          unsigned short int *BEVend)
  439. {
  440.    
  441.    *ChainLength = GetByte();              
  442.    *ErasePulse = GetByte() * 0x100;
  443.    *ErasePulse += GetByte();
  444.    *ProgramPulse = GetByte(); 
  445.    *RowLength = GetByte() * 0x100;
  446.    *RowLength += GetByte();
  447.    *DataSize = GetByte() * 0x100;
  448.    *DataSize += GetByte();   
  449.    *BEVend = GetByte() * 0x100;
  450.    *BEVend += GetByte();
  451.    /*End of the header of the ispSTREAM file.*/   
  452.    
  453. }
  454.  
  455. /*********************************************************************
  456. *                                                                    *
  457. *                     READ_ISPSTREAM_DATA_SIZE                       *
  458. * Extract the data size of the current row from the ispSTREAM file.  *
  459. * Return                                                             *
  460. *     DataSize-----------The data bit length of the current row.     *
  461. **********************************************************************/
  462. void ReadispSTREAMDataSize(unsigned short int  *DataSize)
  463. {
  464.  short int index;
  465.  unsigned short int temp;
  466.  unsigned char xch;
  467.  
  468.  xch=0;
  469.  temp = 0;
  470.  for (index=0; index<16; index++)
  471.      {--bit;
  472.       if (bit<0) 
  473.          {
  474.           curch = GetByte();
  475.           bit=7;
  476.          }
  477.       if ((curch >> bit) & 0x01)  xch |= 0x80 >> index%8;                
  478.       if (index%8==7) {temp = temp * 0x100 + xch; xch=0;}
  479.      }  
  480.    *DataSize = temp;   
  481. }
  482.  
  483. /*****************************************************************
  484. *                                                                *
  485. *                     READ_ISPSTREAM_DATA                        *
  486. * Extract the data from the ispSTREAM file.                      *
  487. *     SF-----------------Super FULL ispSTREAM file if true.      *
  488. * Return                                                         *
  489. *     DataSize-----------The number of data bits  fetched.       *
  490. *     InData-------------The data stream from ispSTREAM file     *
  491. ******************************************************************/
  492. void ReadispSTREAMData(unsigned short int  *DataSize, unsigned char *InData,
  493.                        char SF)
  494. {
  495.  unsigned short int index,size;
  496.  short int j;
  497.  unsigned char xch;
  498.  short int FFcount=0;
  499.  
  500.  
  501.  ReadispSTREAMDataSize(&size);
  502.  if (size > 0)   /*5.001 retain the old size if the current row is NULL*/
  503.  *DataSize = size; 
  504.  j=0;
  505.  xch=0;
  506.  for (index=0; index<size; index++)
  507.      {--bit;
  508.       if (bit<0) 
  509.          {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
  510.              { curch = GetByte(); 
  511.                if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
  512.                FFcount = GetByte();     /*The number of 0xFF bytes*/
  513.              }
  514.           else FFcount--; /*Use up the 0xFF chain first*/
  515.           bit=7;
  516.          }
  517.       if ((curch >> bit) & 0x01)  xch |= 0x80 >> index%8;                
  518.       if (index%8==7) {InData[j++] = xch; xch=0;}
  519.      }  
  520.  if (size > 0)  InData[j] = xch;   /*save the last byte of the current row*//*5.001*/
  521. }
  522.  
  523. /*****************************************************************
  524. *                                                                *
  525. *                     ispInstruction                             *
  526. * Extract the instruction from the ispSTREAM file and clock into *
  527. * the devices or throw away.                                     *
  528. *     SF-----------------Super FULL ispSTREAM file if true.      *
  529. *     Send---------------Send data to devices if true.           *
  530. * Return                                                         *
  531. *     NONE                                                       *
  532. ******************************************************************/
  533. char ispInstruction(char SF, char Send)
  534. {
  535.  unsigned short int index;
  536.  short int i;
  537.  unsigned short int size;
  538.  short int FFcount=0;
  539.  
  540.  #ifdef DEBUG
  541.   printf("\n");
  542.  #endif
  543.  ReadispSTREAMDataSize(&size);
  544.  for (index=0; index<size; index++)
  545.      {--bit;
  546.       if (bit<0) 
  547.          {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
  548.              { curch = GetByte(); 
  549.                if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
  550.                FFcount = GetByte();     /*The number of 0xFF bytes*/
  551.              }
  552.           else FFcount--; /*Use up the 0xFF chain first*/
  553.           bit=7;
  554.          }
  555.       if (Send) /*send the data to the devices*/
  556.          {isp_setpin(out_SDI,(curch >> bit) & 0x01);
  557.  #ifdef DEBUG
  558.   if ((curch >> bit) & 0x01) printf("1"); else printf("0");
  559.  #endif
  560.           if ((jtag)&&(index==size-1)) isp_setpin(out_MODE,HIGH);
  561.           sclock();  /*clock the data into the command registers */
  562.          }
  563.      }
  564.  if ((Send)&&(size > 0)) 
  565.     {execute();  /*execute the instruction if sent*/
  566.      return (1); /*signify data or instruction has actually sent*/
  567.     }
  568.  else return (0); /*no data or instruction send to the devices*/
  569. }
  570.  
  571. /**********************************************************************
  572. *                                                                     *
  573. *                     ispData                                         *
  574. * Send the data stream to devices.                                    *
  575. *    InData-----------The data stream to be sent to devices.          *
  576. *    DataSize---------The length of the data stream.                  *
  577. ***********************************************************************/
  578. void ispData(unsigned char *InData, unsigned short int DataSize)
  579. {
  580.  unsigned short int index;
  581.  short int j;
  582.  unsigned char curch;
  583.  
  584. #ifdef DEBUG
  585.  printf("\n");
  586. #endif
  587.  j=0;
  588.  for (index = 0; index <DataSize; index++) { 
  589.       if (index%8==0) curch = InData[j++];
  590.       isp_setpin(out_SDI, (((curch << index%8) & 0x80) ? 0x01 : 0x00)); 
  591. #ifdef DEBUG
  592.       if ((curch << index%8) & 0x80) printf("1"); else printf("0");
  593. #endif
  594.       if ((jtag)&&(index==DataSize-1)) isp_setpin(out_MODE,HIGH);
  595.       sclock();  /*clock data into the data shift registers */
  596.       }
  597.  if (DataSize> 0) execute();   /*step to shift state*//*5.001*/ 
  598. }
  599.  
  600. /**********************************************************************
  601. *                                                                     *
  602. *                     ispRead                                         *
  603. * Read the data stream from devices and verify.                       *
  604. *    DataSize---------The length of the data stream.                  *
  605. *    OutData----------The data stream to be compare with those read   *
  606. *                     from devices.                                   *
  607. ***********************************************************************/
  608. char ispRead(unsigned short int DataSize, unsigned char *OutData)
  609. {
  610.  unsigned short int index,error;
  611.  unsigned char xch,cur_bit;
  612.  short int j;
  613.  #ifdef DEBUG
  614.  printf("\n");
  615.  #endif
  616.  j=0;
  617.  error=0;
  618.  xch=0;
  619.  for (index = 0; index <DataSize; index++) { 
  620.       if (index%8==0) xch = OutData[j++];
  621.       cur_bit=isp_SDO(); 
  622.  #ifdef DEBUG
  623.       if (cur_bit) printf("H"); else printf("L");
  624.  #endif
  625.       if (cur_bit != (((xch << index%8) & 0x80) ? 0x01 : 0x00)) error++;  
  626.       if ((jtag)&&(index==DataSize-1)) isp_setpin(out_MODE,HIGH);
  627.       sclock();  /*clock data out from the data shift registers */
  628.       }
  629.  execute();   /*step to shift state*/ 
  630.  if (error > 0) return 1;      /*Flag failure occur*/
  631.  else return (OK);
  632. }
  633.  
  634. /**********************************************************************
  635. *                                                                     *
  636. *                     ispDisplay                                      *
  637. * Read the data stream from devices and display                       *
  638. *    DataSize---------The length of the data stream.                  *
  639. *    OutData----------The data stream read from devices.              *
  640. *                                                                     *
  641. * This function is for reading and displaying the UES of the ispLSI   *
  642. * devices. If the JEDEC file of the ispLSI devices containing UES     *
  643. * data, the UES data in the ispLSI devices will be read and displayed *
  644. * when calling this function. For example:                            *
  645. *                    1032E pv 1032e.jed                               *
  646. *                    2096  pv 2096.jed                                *
  647. *                    3256A pv 3256a.jed                               *
  648. * If only the JEDEC files 1032e.jed and 2096.jed files have UES data  *
  649. * then the UES data of 1032E and 2096 will be read and displayed as a *
  650. * continuous UES string. Please note that the UES of ispGAL22v10 and  *
  651. * ispGDS can't supported by this function due to the fact that the UES*
  652. * are part of the ARRAY of those devices. Please also note that the   *
  653. * actual length of UES row can be longer than what is published.      *
  654. * For example: The UES row of 3256a is actually 338 bits long whereas *
  655. * the published UES length is 160. The extra bits are filled with 1s  *
  656. * by the ispSTREAM writter.  This function can read and display only  *
  657. * the full length of the UES row. It can't mask out the dummy bits.   *
  658. * It is strongly recommended that only one device is selected in a    *
  659. * time in a daisy chain for reading and displaying UES.               *
  660. ***********************************************************************/
  661. char ispDisplay(unsigned short int DataSize, unsigned char *OutData)
  662. {
  663.  unsigned short int index;
  664.  unsigned char xch,cur_bit;
  665.  unsigned short int j;
  666.  j=0;
  667.  xch=0;
  668.  for (index = 0; index <DataSize; index++) { 
  669.       cur_bit=isp_SDO(); 
  670.       if (cur_bit) xch |= (0x80 >> index%8);
  671.       if (index%8==7) {OutData[j++] = xch;
  672.                        xch=0;}
  673.       if ((jtag)&&(index==DataSize-1)) isp_setpin(out_MODE,HIGH);
  674.       sclock();  /*clock data out from the data shift registers */
  675.       }
  676.    OutData[j] = xch; /*store the last byte*/
  677.    printf("\nThe UES string in HEX:\n");
  678.    for (index = 0; index < DataSize/8; index++)
  679.        printf("%02x",OutData[index]);
  680.    printf("\nThe UES string in ASCII:\n");
  681.    for (index = 0; index < DataSize/8; index++)
  682.        {if (isprint(OutData[index])) printf("%c",OutData[index]);
  683.         else printf(".");
  684.        }
  685.    printf("\n");
  686.  execute();   /*step to shift state*/ 
  687.  return (OK);
  688. }
  689.  
  690. /*************************************************************
  691. *                                                            *
  692. *                     ISPSTREAM_PUMP                         *
  693. *                                                            *
  694. *************************************************************/
  695.  
  696. short int   ispstream_pump(short int operation, short int *end)
  697. {
  698.    short int       row;
  699.    char            SF;                    /*ispSTREAM file types identifier*/
  700.    char            send;                  /*send data to devices if true*/
  701.    char            ready;                 /*5.001 ready to verify data*/
  702.    unsigned char   FileType;
  703.    short int       last_row,
  704.                    erase_pulse,
  705.                    program_pulse,
  706.                    devices_in_chain;
  707.    unsigned short int    maxi_data,
  708.                          data_length,
  709.                             be_row;
  710.    short int       rcode,condition;
  711.    unsigned char   *buf;
  712.  
  713.    row =0;
  714.    bit = 0;
  715.    jtag= false;
  716.    /*Start reading the header of the ispSTREAM file*/
  717.    FileType = GetByte();
  718.    if (FileType == 0xF0) {SF=false;
  719.                           jtag=true;}         /*Check for correct file type*/
  720.    else if (FileType == 0x0b ) {SF=true;
  721.                                 jtag=true;}   /*Super FULL ispSTREAM file found*/ 
  722.    else if (FileType == 0x0F) {SF=false;}     /*Check for correct file type*/
  723.    else if (FileType == 0x0a ) {SF=true;}     /*Super FULL ispSTREAM file found*/ 
  724.    else {
  725.         return FILE_NOT_JEDEC;
  726.        }
  727.    ReadispSTREAMHeader(&devices_in_chain, &erase_pulse, &program_pulse,
  728.                            &last_row, &maxi_data, &be_row);
  729.    rcode = OK;                                /*Success by default.*/
  730.    if ((operation==verify)||(operation==verify_ues)
  731.         ||(operation==read_show_ues))       /*verify only*/
  732.       {erase_pulse=0;                       /*void the erase instruction*/ 
  733.        program_pulse=0;                     /*void the program instruction*/
  734.       }
  735.    
  736.    /*Allocate memory to store one row of data from the ispSTREAM file.*/
  737.    if ((buf = (unsigned char *) malloc(maxi_data/8+1))==NULL)
  738.       {free(buf);
  739.        return FILE_TOO_BIG;
  740.       }
  741.  
  742.    /*set the initial condition of the parallel port*/
  743.    /*     All the port_pins defined on lattice.h will be controlled by
  744.           ispstream_pump(). The rest can be initialized here either to
  745.           HIGH or LOW and won't be altered by isptream_pump*/
  746.             
  747.    isp_pins = NUL;          /* intialize to drive all port pins LOW*/
  748.    isp_setpin(out_ISP, LOW);/*  drive ispEN pin low to enable the 
  749.                                    ispJTAG controlling pins:
  750.                                    TCK,TMS,TDI and TDO.*/ 
  751.    move_to_id_state();      /* Go to Reset then Run-Test/Idle state*/
  752.    execute();
  753.    move_to_id_state();
  754.    if (jtag)                /* for ispJTAG chain only*/
  755.       {
  756.        isp_setpin(out_MODE,HIGH); 
  757.        sclock();
  758.        isp_setpin(out_MODE,LOW);
  759.        sclock(); sclock();
  760.        state=execute_state;     /* At shift-DR state*/
  761.        isp_setpin(out_SDI,HIGH);
  762.       }
  763.    ReadispSTREAMData(&data_length,buf,SF);   /*fetch ID stream from ispSTREAM*/
  764.    rcode = ispRead(data_length,buf);            /*verify the ID stream*/    
  765.    if (rcode != OK)     
  766.       {
  767.        if (buf != NULL)
  768.        free(buf);
  769.        return UNKNOWN_CHIP;      
  770.       }
  771.    for (row=1; row<be_row; row++)   
  772.        {switch(row)
  773.          { case 8:program_enable(devices_in_chain);/*enable programming*/ 
  774.                   if (erase_pulse > 0)             /*erase the devices*/
  775.                     {
  776.                      state=time_state;
  777.                      ispInstruction(SF,true);
  778.                      sclock();                    /*start the erase timing*/
  779.                      pulse_width(erase_pulse);    /*erase pulse*/
  780.                      isp_setpin(out_MODE, HIGH);
  781.                      isp_setpin(out_SDI, HIGH);
  782.                      if (!jtag) pulse_width(1);   /*super voltage discharge*/
  783.                      isp_setpin(out_SCLK,HIGH);
  784.                      if (jtag) pulse_width(1);    /*super voltage discharge*/
  785.                      isp_setpin(out_SCLK,LOW);
  786.                      if (jtag) sclock(); 
  787.                      isp_setpin(out_SDI,LOW);
  788.                      isp_setpin(out_MODE,LOW);    
  789.                      sclock(); sclock();          /*devices in shift state*/
  790.                      state=shift_state;
  791.                     }
  792.                   else ispInstruction(SF,false); /*skipp BULK ERASE*/
  793.                  break;
  794.          default:if (((row-9)%12==3)||((row-9)%12==8)) /*skipp BULK ERASE verify*/
  795.                     ReadispSTREAMDataSize(&data_length);         
  796.                  else ispInstruction(SF,false);    
  797.                  break;}
  798.        }
  799.    /*start processing the rows in the ispSTREAM file*/
  800.    data_length = 0;
  801.    ready=false;          /*5.001*/
  802.    for (; row <= last_row; row++) {
  803.        *end = row;                               /* The row number where process ended.*/
  804.        if (row==last_row) condition = 8;         /* security programming*/
  805.        else condition = (row-9) % 12;
  806.        if (((operation==verify_ues)||(operation==read_show_ues))
  807.           &&(row <= last_row-DATAROW)) send = false;
  808.        else send = true;
  809.        switch(condition){
  810.            case 0:                              /*address shift*/
  811.            case 1:ispInstruction(SF,send);      /*address data*/
  812.                   break;
  813.            case 2:                              /*data shift*/
  814.            case 7:ready=ispInstruction(SF,send);/*data shift*//*5.001*/
  815.                   break;
  816.            case 3:                              /*shift data in/out of devices*/
  817.            case 8:
  818.                   if ((data_length > 0)&&(ready))  /*5.001 verify the data shifted in*/
  819.                      {state=idle_state;           /*loop back to Shift-DR*/
  820.                       rcode = ispRead(data_length,buf);   
  821.                       if (!jtag) execute();       /*back to shift state for ISP chain*/
  822.                       state=execute_state;        /*back to shift-DR state*/
  823.                       data_length=0;              /*5.001 data verified*/
  824.                      }
  825.                   ReadispSTREAMData(&data_length,buf,SF); /*fetch data stream from ispSTREAM*/
  826.                   if (ready) ispData(buf,data_length);    /*send data into devices*/
  827.                   break;
  828.            case 4:
  829.            case 9:if (program_pulse > 0)        /*program and verify*/
  830.                      {
  831.                       state=time_state;
  832.                       if (ispInstruction(SF,true))    /*5.001 program commands exist*/
  833.                          {sclock();                   /*start program timing*/
  834.                           pulse_width(program_pulse);
  835.                           execute();                  /*step to shift state*/
  836.                          }
  837.                      state=shift_state;               /*5.001 at Shift-IR*/
  838.                      }
  839.                   else ispInstruction(SF,false);   /*skip programming*/
  840.                   break;
  841.            case 5:
  842.           case 10:state=time_state;
  843.                   if (ispInstruction(SF,send))         /*verify*/
  844.                     {sclock();                           /*start verify timing*/
  845.                      pulse_width(1);                     /*30uS min. verify time*/
  846.                      execute();                          /*step to shift state*/
  847.                     }
  848.                   state=shift_state;                   /*5.001 at Shift-IR*/
  849.                   break;
  850.            case 6:
  851.           case 11:if (ispInstruction(SF,send))
  852.                   {   
  853.                       if (operation==read_show_ues)     /*read and display ues*/
  854.                          rcode = ispDisplay(data_length,buf);
  855.                       else 
  856.                       rcode = ispRead(data_length,buf);   /*verify the data stream*/
  857.                       data_length=0;                      /*don't verify again*/
  858.                   }
  859.                   break;
  860.           default:break;
  861.          }
  862.        if (rcode != OK) break;  
  863.        }                              
  864.            
  865.    device_enable(devices_in_chain);  /*activate the devices*/
  866.    isp_setpin(out_ISP,HIGH);  /*activate the ispLSI devices*/
  867.    if (buf != NULL) free(buf);
  868.    if (rcode==OK) 
  869.       return (OK);
  870.    else  return VALIDATION_ERROR;      
  871.  
  872. }
  873.  
  874.  
  875. /*************************************************************
  876. *                                                            *
  877. *                         error_handler                      *
  878. *                                                            *
  879. *  rcode                  - error code                       *
  880. *                                                            *
  881. *                                                            *
  882. *  This procedure return the address of the message string   *
  883. *  for the corresponding error code.                         *
  884. *                                                            *
  885. *************************************************************/
  886.  
  887. void error_handler(short int rcode, char *message)
  888. {
  889.  
  890. char *error_message[] = {{"PASS"},{""},{""},{"PC Hardware Problem"},{""},
  891.                    {""},{""},
  892.                    {"No Device Found/Open Download Cable/Open Daisy Chain"},
  893.                    {"Can't Find the File"},{""},{"Not Enough PC Memory"},
  894.                    {"Verification Fail"},{""},{""},
  895.                    {""},
  896.                    {"The Chip Count in the Chain and the File Do Not Match"},
  897.                    {"Unknown Device Found"},{"Wrong File Type"},{"File Error"},
  898.                    {""}};
  899.  
  900.  strcpy(message, error_message[-rcode]);
  901.  
  902. /*************************************************************
  903. *                                                            *
  904. *                            MAIN                            *
  905. *                                                            *
  906. *************************************************************/
  907.  
  908. int             main(int argc, char *argv[])
  909. {
  910.    short int       rcode = OK,
  911.                    end = 0;
  912.    char           *ptr,
  913.                    filename[300],
  914.                    str[300];
  915.    short int operation=prog_verify;  /*3.05 Default to Program and Verify*/
  916.  
  917.  
  918.    printf("\n             Lattice Semiconductor Corp.\n");
  919.    printf("\n            ispCODE V5.00  Copyright 1997\n");
  920.    printf("\n ispSTREAM Driver for simple ispJTAG chain or ISP chain\n\n");
  921.  
  922.    if ((argc < 2) || (argc > 3)) {
  923.       printf("\nUsage: xturbo [drive:][path]isp_filename [operation] \n");
  924.       printf("Example: xturbo my_file.isp pv\n");
  925.       printf("\n");
  926.       printf("isp_filename         The ispSTREAM File Created From A Valid \n");
  927.       printf("                     Daisy Chain Configuration File\n");
  928.       printf("operation            \"pv\" = program and verify\n");
  929.       printf("                     \"v\" = Verify only\n");
  930.       printf("                     \"uv\" = Verify UES only\n");
  931.       printf("                     \"ud\" = Read and display UES from devices.\n");
  932.       printf("                     Default to pv if operation is not entered.\n");                            
  933.       exit(1);
  934.    }
  935.  
  936.    if ((fp = fopen(argv[1], "rb")) == NULL) {
  937.       printf("\n%s File not found!\n", argv[1]);
  938.       exit(1);
  939.    }
  940.  
  941.    strcpy(str, argv[1]);
  942.    ptr = strchr(str, '.');
  943.    if (ptr)
  944.       *ptr = '\0';
  945.    sprintf(filename, "%s.isp", str);
  946.    strcpy(str, argv[1]);
  947.    if (stricmp(str, filename)) {
  948.       printf("\nFile %s Is Not An ispSTREAM File\n", str);
  949.       fclose(fp);
  950.       exit(1);
  951.    }
  952.       if (rcode == OK){        /*start programming and verification*/
  953.                 
  954.           if(!strcmp(strlwr(argv[2]),"uv")){                  /*3.05 What to do? uv=ues verify only*/
  955.               operation=verify_ues;                                      /*for verify ues only =1*/  
  956.               printf("\nStart Verify UES of ispLSI devices.......\n");}  
  957.           else if(!strcmp(strlwr(argv[2]),"ud")){               /*ud = verify only*/
  958.               operation=read_show_ues;
  959.               printf("\nStart Read and Display UES of ispLSI devices .......\n");}
  960.           else if(!strcmp(strlwr(argv[2]),"v")){               /*v = verify only*/
  961.               operation=verify;
  962.               printf("\nStart Verify.......\n");}
  963.           else {                                               /*pv = program and verify: Default*/
  964.                   operation=prog_verify;
  965.                   printf("\nStart Program and Verify.......\n");
  966.                }    
  967.         rcode = ispstream_pump(operation, &end);       /*3.05 add operation switch*/
  968.        }
  969.    fclose(fp);   
  970.    if (rcode != OK) {
  971.       error_handler(rcode, str);
  972.       printf("\nFailed At Row %d in Program and Verify Due To %s\n", end, str);
  973.       printf("\n");
  974.       printf("+-------+\n");
  975.       printf("| FAIL! |\n");
  976.       printf("+-------+\n");
  977.       exit (-rcode);
  978.    } else {
  979.       printf("\n");
  980.       printf("+=======+\n");
  981.       printf("| PASS! |\n");
  982.       printf("+=======+\n");
  983.    }
  984.  
  985.    return (0);
  986. }
  987.